﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Genuilder.Tests
{
	public class TestDirectory : IDisposable
	{
		public TestDirectory(string name = null)
		{
			if(name == null)
				name = Guid.NewGuid().ToString();
			_Path = name;
			_DirectoryInfo = new DirectoryInfo(_Path);
			_DirectoryInfo.Create();
		}
		private readonly DirectoryInfo _DirectoryInfo;
		public DirectoryInfo DirectoryInfo
		{
			get
			{
				return _DirectoryInfo;
			}
		}
		public TestDirectory Of(string directory)
		{
			var dest = new DirectoryInfo(directory);
			Copy(_DirectoryInfo, dest);
			return this;
		}

		private void Copy(DirectoryInfo dest, DirectoryInfo source)
		{
			foreach(var file in source.GetFiles())
			{
				file.CopyTo(System.IO.Path.Combine(dest.FullName, file.Name), true);
			}
			foreach(var directory in source.GetDirectories())
			{
				var subDirectory = dest.CreateSubdirectory(directory.Name);
				Copy(subDirectory, directory);
			}
		}

		#region IDisposable Members

		public void Dispose()
		{
			_DirectoryInfo.Delete(true);
		}

		#endregion

		private readonly string _Path;
		public string Path
		{
			get
			{
				return _Path;
			}
		}

		public void CreateFile(string file)
		{
			File.Create(System.IO.Path.Combine(Path, file)).Close();
		}

		public TestDirectory CreateSubDirectory(string name)
		{
			return new TestDirectory(System.IO.Path.Combine(Path, name));
		}

		public void CreateFiles(params string[] files)
		{
			foreach(var file in files)
				CreateFile(file);
		}

		public IEnumerable<string> EnumerateFiles()
		{
			return EnumerateFiles("", DirectoryInfo);
		}

		private IEnumerable<string> EnumerateFiles(string prefix, DirectoryInfo directory)
		{
			bool hasPrefix = !String.IsNullOrEmpty(prefix);
			foreach(var file in directory.GetFiles())
			{
				if(!hasPrefix)
					yield return file.Name;
				else
					yield return System.IO.Path.Combine(prefix, file.Name);
			}
			foreach(var subDirectory in directory.GetDirectories())
			{
				foreach(var subFile in EnumerateFiles(hasPrefix ? System.IO.Path.Combine(prefix, subDirectory.Name) : subDirectory.Name, subDirectory))
				{
					yield return subFile;
				}
			}
		}
	}
}
